/** <!--------------------------------------------------------------------------------------------->
 * @file RevGraphBranch.h
 *
 * GSvn - A Graphical Client for SVN
 * Copyright (C) 2012  Karl Krach, gsvn@bluespirit.la
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 <!---------------------------------------------------------------------------------------------> */


#ifndef REVGRAPHBRANCH_H
#define REVGRAPHBRANCH_H

// -- includes --
#include <QGraphicsItem>
#include "RevModelItem.h"
#include "RevGraphBranchLink.h"
#include "RevGraphItem.h"
#include "RevGraphItemMap.h"

// --- forward declarations ---
class RevGraphItem;

// --- namespaces ---
// --- defines ---


/** <!--------------------------------------------------------------------------------------------->
 * A graphics item which represents a branch.
 *
 * @author	Karl Krach, <gsvn@bluespirit.la>
 * @since	2012-02-27
 <!---------------------------------------------------------------------------------------------> */
class RevGraphBranch : public QGraphicsItem
{

	/* Con-/Destructors */
public:

	/** <!----------------------------------------------------------------------------------------->
	 * Creates the RevGraphBranch object
	 <!-----------------------------------------------------------------------------------------> */
	RevGraphBranch( const QString& strName );

	/** <!----------------------------------------------------------------------------------------->
	 * Deletes the RevGraphBranch object
	 <!-----------------------------------------------------------------------------------------> */
	virtual ~RevGraphBranch();


	/* Methods */
public:

	/** <!----------------------------------------------------------------------------------------->
	 * Sets the branch link (iterator object of the branch-map which connects all branches)
	 <!-----------------------------------------------------------------------------------------> */
	void setBranchLink( const RevGraphBranchLink& pBranchLink );

	/** <!----------------------------------------------------------------------------------------->
	 * Returns true, when the given item was already added to this branch
	 <!-----------------------------------------------------------------------------------------> */
	bool containsItem( RevGraphItem* pItem ) const;

	/** <!----------------------------------------------------------------------------------------->
	 * Adds an item to the branch
	 *
	 * @param pItem (in) item to add
	 <!-----------------------------------------------------------------------------------------> */
	void addItem( RevGraphItem* pItem );

	/** <!----------------------------------------------------------------------------------------->
	 * Removes the given item from the branch
	 *
	 * @param pItem (in) item to remove
	 <!-----------------------------------------------------------------------------------------> */
	void removeItem( RevGraphItem* pItem );

	/** <!----------------------------------------------------------------------------------------->
	 * Removes all items from this branch
	 <!-----------------------------------------------------------------------------------------> */
	void removeAllItems();

	/** <!----------------------------------------------------------------------------------------->
	 * Calculates the bounding rectangular of all child elements
	 *
	 * @returns the bounding rectangular of all child elements
	 <!-----------------------------------------------------------------------------------------> */
	QRectF calculateChildBoundingRect() const;

	/** <!----------------------------------------------------------------------------------------->
	 * Calculates the y-position of this branch (browses through all branches and returns the y-pos
	 * of the first item
	 *
	 * @returns the y-position of this branch
	 <!-----------------------------------------------------------------------------------------> */
	qreal calculateYPosition() const;

	/** <!----------------------------------------------------------------------------------------->
	 * Returns the name of the branch
	 *
	 * @returns the name of the branch
	 <!-----------------------------------------------------------------------------------------> */
	QString getName() const { return m_strName; }

	/** <!----------------------------------------------------------------------------------------->
	 * Sets the name of the branch
	 *
	 * @param strName (in) the name to set
	 <!-----------------------------------------------------------------------------------------> */
	void setName( QString strName ) { m_strName = strName; }

	/** <!----------------------------------------------------------------------------------------->
	 * Returns true if this branch has at least one item
	 *
	 * @returns true if this branch has at least one item
	 <!-----------------------------------------------------------------------------------------> */
	bool hasItem() const { return !m_aItems.isEmpty(); }

	/** <!----------------------------------------------------------------------------------------->
	 * Returns the first item of this branch
	 *
	 * @returns the first item of this branch
	 <!-----------------------------------------------------------------------------------------> */
	RevGraphItem* getFirstItem() const { return m_aItems.getFirst(); }


	/* Override QGraphicsItem */
public:

	/** <!----------------------------------------------------------------------------------------->
	 * This function defines the outer bounds of the item as a rectangle; all painting must be
	 * restricted to inside an item's bounding rect. QGraphicsView uses this to determine whether
	 * the item requires redrawing.
	 *
	 * Note: For shapes that paint an outline / stroke, it is important to include half the pen
	 * width in the bounding rect. It is not necessary to compensate for antialiasing, though.
	 *
	 * @returns the item's bounding rect
	 <!-----------------------------------------------------------------------------------------> */
	QRectF boundingRect() const;

	/** <!----------------------------------------------------------------------------------------->
	 * This function, which is usually called by QGraphicsView, paints the contents of an item in
	 * local coordinates.
	 *
	 * @param pPainter (in) painter to paint the graphics item
	 * @param pOption  (in) provides the style for the item (such as its state, exposed area, etc)
	 * @param pWidget  (in) points to the widget that is being painted on
	 <!-----------------------------------------------------------------------------------------> */
	void paint( QPainter* pPainter, const QStyleOptionGraphicsItem* pOption, QWidget* pWidget );

	/** <!----------------------------------------------------------------------------------------->
	 * Receives all events of the watched graphics item.
	 *
	 * Reimplementations must return true to prevent further processing of a given event, ensuring
	 * that it will not be delivered to the watched item, or return false to indicate that the event
	 * should be propagated further by the event system.
	 *
	 * @param pWatched (in) watched graphics item
	 * @param pEvent   (in) filtered event
	 * @returns true, when this event shall be blocked
	 <!-----------------------------------------------------------------------------------------> */
	bool sceneEventFilter( QGraphicsItem* pWatched, QEvent* pEvent );

	/** <!----------------------------------------------------------------------------------------->
	 * This virtual function is called by QGraphicsItem to notify custom items that some part of
	 * the item's state changes. By reimplementing this function, your can react to a change, and in
	 * some cases, (depending on change,) adjustments can be made.
	 *
	 * @param eChange (in) is the parameter of the item that is changing
	 * @param oValue  (in) is the new value; the type of the @a oValue depends on @a eChange
	 <!-----------------------------------------------------------------------------------------> */
	QVariant itemChange( GraphicsItemChange eChange, const QVariant& oValue );


	/* Members */
private:

	/** <!----------------------------------------------------------------------------------------->
	 * Name of the branch
	 <!-----------------------------------------------------------------------------------------> */
	 QString m_strName;

	/** <!----------------------------------------------------------------------------------------->
	 * Iterator object of the branch-map which connects all branches
	 <!-----------------------------------------------------------------------------------------> */
	RevGraphBranchLink* m_pBranchLink;

	/** <!----------------------------------------------------------------------------------------->
	 * List of branch items
	 <!-----------------------------------------------------------------------------------------> */
	RevGraphItemMap m_aItems;

	/** <!----------------------------------------------------------------------------------------->
	 * Space and hight of branch indicator
	 <!-----------------------------------------------------------------------------------------> */
	static const int S_HEIGHT=70, S_SPACE=5;

};	// END class RevGraphBranch

#endif // REVGRAPHBRANCH_H
